home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / midi / dskchngr.lha / DiskChanger / Source / DiskChanger.c next >
C/C++ Source or Header  |  1995-08-15  |  13KB  |  559 lines

  1. /*
  2.     as always, the source.
  3.     there are many bugs and other thingies wrong here.
  4.     this was "developed" during some work at university
  5.     and its origin is one year ago.
  6.  
  7.     daniel.
  8. */
  9.  
  10. #define VERSION        1        // fast völlig nutzlos
  11. #define REVISION    2
  12.  
  13. #define PREFSFILENAME    "DiskChanger.prefs"
  14.  
  15. #include <exec/exec.h>
  16. #include <dos/dos.h>
  17. #include <devices/timer.h>
  18. #include <rexx/storage.h>
  19. #include <proto/exec.h>
  20. #include <proto/dos.h>
  21. #include <proto/rexxsyslib.h>
  22. #include <misc/deliplayer.h>
  23.  
  24. /* taken from the gadtoolsbox generated source */
  25.  
  26. #include <exec/types.h>
  27. #include <intuition/intuition.h>
  28. #include <intuition/classes.h>
  29. #include <intuition/classusr.h>
  30. #include <intuition/imageclass.h>
  31. #include <intuition/gadgetclass.h>
  32. #include <libraries/gadtools.h>
  33. #include <graphics/displayinfo.h>
  34. #include <graphics/gfxbase.h>
  35. #include <clib/exec_protos.h>
  36. #include <clib/intuition_protos.h>
  37. #include <clib/gadtools_protos.h>
  38. #include <clib/graphics_protos.h>
  39. #include <clib/utility_protos.h>
  40. #include <string.h>
  41. #include <clib/diskfont_protos.h>
  42.  
  43. #include "gui.h"
  44.  
  45. #include <string.h>
  46.  
  47. enum { IMMEDIATE=0, LOADNOPLAY, WAITSONGEND };
  48.  
  49. #define AllocStruct(X)    AllocVec(sizeof(struct X),MEMF_CLEAR|MEMF_PUBLIC)
  50. #define FreeStruct(X)    FreeVec(X)
  51.  
  52. #define CHANGESIGNAL    (1L << (ULONG)changesignal)
  53. #define DELISIGNAL    (1L << DeliPort->mp_SigBit)
  54. #define TIMESIGNAL    (1L << timeport->mp_SigBit)
  55.  
  56. extern VOID DiskChangeHandler (VOID);
  57.  
  58. ULONG init_player (void);
  59. ULONG end_player (void);
  60. ULONG appear (void);
  61. ULONG disappear (void);
  62.  
  63. ULONG DeliTags[] = {
  64.     DeliHeader("Diskchanger",8192,0,DELIVERSION),
  65.     
  66.     DTP_Creator,        (ULONG) "Daniel Balster, dbalster#amigager _ //"
  67.                     "Max-Reger Weg 48, 33100 Paderborn \\X/ "
  68.                     "email: dbalster@uni-paderborn.de   ¯  ",
  69.     DTP_Description,    (ULONG) "Lädt automatisch die entsprechende Pro"
  70.                     "grammliste ein, wenn man ein Medium in"
  71.                     "ein Laufwerk einlegt (oder entfernt!) ",
  72.     DTP_PlayerVersion,    (VERSION<<16)|REVISION,
  73.     
  74.     DTP_InitPlayer,        (ULONG) init_player,
  75.     DTP_EndPlayer,        (ULONG) end_player,
  76.  
  77.     DTP_Appear,        (ULONG) appear,
  78.     DTP_Disappear,        (ULONG) disappear,
  79.  
  80.     DTP_RequestKickVersion,    (ULONG) 37,
  81.  
  82.     TAG_DONE
  83. };
  84.  
  85. ULONG changesignal;    /* global for export */
  86.  
  87. ULONG WINDOWSIGNAL = 0;    /* semaphore like used */
  88.  
  89. BOOL running = TRUE;
  90. BOOL handler = FALSE;
  91. BOOL waitplay = FALSE;
  92.  
  93. struct MsgPort *mp;
  94. struct IOStdReq *ior;
  95. struct Interrupt *irq;
  96.  
  97. /********  Prefs Settings  *****************************/
  98.  
  99. UBYTE adosname [10] = { "CD0:" };
  100. UBYTE volumename [256];
  101. UBYTE devicename [256];
  102. ULONG unitnumber;
  103.  
  104. UBYTE insertscript [256] = { "execute s:deliinsertdisk VOLUME %s DATABASE %s" };
  105. UBYTE removescript [256] = { "execute s:deliinsertdisk DATABASE %s" };
  106. UBYTE databasename [256] = { "S:Media.database" };
  107.  
  108. BOOL Popup    = TRUE;
  109. BOOL Activate    = TRUE;
  110.  
  111. ULONG windowX=0, windowY=0;
  112.  
  113. UWORD InsertDelay = 150;
  114. UWORD RemoveDelay = 800;
  115. UWORD ProgramMode = 1;
  116.  
  117. /*******************************************************/
  118.  
  119. VOID playlist (BOOL mode)
  120. {
  121.     UBYTE prglist[512];
  122.     UBYTE tmpbuf[512];
  123.  
  124.     if(GetVar("DELIPROGRAM",prglist,512,GVF_GLOBAL_ONLY)>0)
  125.     {
  126.         if (mode)
  127.             sprintf(tmpbuf,"run <>NIL: sys:rexxc/rx \"address DELITRACKER;'clearlist';'makelist' '%s';'playlist' 1;\"",prglist);
  128.         else
  129.             sprintf(tmpbuf,"run <>NIL: sys:rexxc/rx \"address DELITRACKER;'clearlist';'makelist' '%s';\"",prglist);
  130.         
  131.         Execute(tmpbuf,0,0);
  132.     }
  133.     else Execute("run <>NIL: C:RequestChoice \"Error\" \"$DELIPROGRAM was not set correct ???\" ok",0,0);
  134. }
  135.  
  136. //
  137. // copy a BSTR to a normal string
  138. //
  139. // BCPL sucks
  140. //
  141.  
  142. VOID bstrcpy (UBYTE *a, UBYTE *b)
  143. {
  144.     int i;
  145.     for (i=1;i<=b[0];i++) a[i-1] = b[i];
  146.     a[i-1]=0;
  147. }
  148.  
  149. //
  150. // get the VOLUME and DEVICE name and the unit number from an AmigaDOS device descriptor, i.e. "DF0:"
  151. // is a valid device descriptor. there is no complex error checking yet (including user-dialog).
  152. // if an error occurs here then install_handler will fail and the Genie is going to exit.
  153. //
  154.  
  155. VOID getVolume (VOID)
  156. {
  157.     struct InfoData *id;
  158.     BPTR lock;
  159.     struct DosList *dl;
  160.  
  161.     if( id = AllocVec (sizeof(struct InfoData),MEMF_CLEAR|MEMF_PUBLIC))
  162.     {
  163.         if (lock = Lock (adosname,ACCESS_READ))
  164.         {
  165.             if (Info(lock,id))
  166.             {
  167.                 dl = (struct DosList*)BADDR(id->id_VolumeNode);
  168.                 bstrcpy(volumename,BADDR(dl->dol_Name));
  169.             }
  170.             UnLock(lock);
  171.         }
  172.         FreeVec(id);
  173.     }
  174. }
  175.  
  176.  
  177. VOID getDeviceUnit (VOID)
  178. {
  179.     struct DosList *dl;
  180.     struct DeviceNode *dn;
  181.     struct FileSysStartupMsg *fssm;
  182.     adosname[strlen(adosname)-1]=0; // un-colon
  183.     dl = LockDosList(LDF_DEVICES|LDF_READ);
  184.     dl = FindDosEntry(dl,adosname,LDF_DEVICES|LDF_READ);
  185.     dn = (struct DeviceNode*) dl;
  186.     fssm = BADDR(dn->dn_Startup);
  187.     unitnumber = fssm->fssm_Unit;
  188.     bstrcpy(devicename,BADDR(fssm->fssm_Device));
  189.     UnLockDosList(LDF_DEVICES|LDF_READ);
  190.     adosname[strlen(adosname)]=':'; // re-colon
  191. }
  192.  
  193. //
  194. // install the handler. if it fails it returns FALSE
  195. //
  196.  
  197. BOOL install_handler (STRPTR device, ULONG unit)
  198. {
  199.     handler    = FALSE;
  200.     irq    = NULL;
  201.     mp    = NULL;
  202.     ior    = NULL;
  203.  
  204.     if (!(irq=AllocStruct(Interrupt))) return FALSE;
  205.  
  206.     if(!(mp=CreateMsgPort())) return FALSE;
  207.  
  208.     if(!(ior=(struct IOStdReq*)CreateIORequest(mp,sizeof(struct IOStdReq)))) return FALSE;
  209.  
  210.     if(OpenDevice(device,unit,ior,0)) return FALSE;
  211.     
  212.     bzero(irq,sizeof(struct Interrupt));
  213.     
  214.     irq->is_Code        = DiskChangeHandler;
  215.     irq->is_Data        = (APTR) FindTask(0);
  216.     irq->is_Node.ln_Pri    = 10;
  217.     irq->is_Node.ln_Type    = NT_INTERRUPT;
  218.     irq->is_Node.ln_Name    = "DiskChangeHandler";
  219.     
  220.     ior->io_Command        = TD_ADDCHANGEINT;
  221.     ior->io_Flags        = 0;
  222.     ior->io_Length        = sizeof(struct Interrupt);
  223.     ior->io_Data        = (APTR) irq;
  224.     SendIO(ior);
  225.  
  226.     return (BOOL) (handler = ((ior->io_Error==0)?TRUE:FALSE));       
  227. }
  228.  
  229. //
  230. // remove the handler
  231. //
  232.  
  233. VOID remove_handler (VOID)
  234. {
  235.     if (handler)
  236.     {
  237.         ior->io_Command    = TD_REMCHANGEINT;
  238.         ior->io_Flags    = 0;
  239.         ior->io_Length    = sizeof(struct Interrupt);
  240.         ior->io_Data    = (APTR) irq;
  241.         DoIO(ior);
  242.  
  243.         CloseDevice((struct IORequest*)ior);
  244.     }
  245.  
  246.     if (ior) DeleteIORequest((struct IORequest*)ior);
  247.     if (mp) DeleteMsgPort(mp);
  248.     if (irq) FreeStruct(irq);
  249.     
  250.     irq    = NULL;
  251.     mp    = NULL;
  252.     ior    = NULL;
  253.     handler    = FALSE;
  254. }
  255.  
  256. ULONG init_player (void)
  257. {
  258.     return 0;        // unused...
  259. }
  260.  
  261. ULONG end_player (void)
  262. {
  263.     return 0;
  264. }
  265.  
  266. void newDevice (void)
  267. {
  268.     remove_handler();
  269.     getDeviceUnit();
  270.     running = install_handler(devicename,unitnumber);
  271.     
  272.     if (!running)
  273.     {
  274.         strcpy(adosname,"CD0:");
  275.         remove_handler();
  276.         getDeviceUnit();
  277.         running = install_handler(devicename,unitnumber);
  278.     }
  279. }
  280.  
  281. void showAbout (void)
  282. {
  283.     ULONG   idcmp = 0;
  284.     struct EasyStruct eas;
  285.  
  286.     eas.es_StructSize    =   sizeof(struct EasyStruct);
  287.     eas.es_Flags    =   NULL;
  288.     eas.es_Title    =   "Diskchanger V1.2";
  289.     eas.es_GadgetFormat =   "Ok";
  290.     eas.es_TextFormat=    "          Diskchanger Genie\n"
  291.                 "       ©1995 by Daniel Balster\n"
  292.                 "     (dbalster@uni-paderborn.de)\n"
  293.                 "         All Rights Reserved.\n\n"
  294.                 "This genie is a gift and can be used\n"
  295.                 " with the DeliTracker distribution.";
  296.  
  297.     EasyRequestArgs( NULL, &eas, &idcmp, 0 );
  298. }
  299.  
  300. void savePrefs (void)
  301. {
  302.     BPTR file;
  303.     char configdir[256];    // constant strings are shit in normal C; my generic C++ string class is much better ;-(
  304.     char filename[512];
  305.  
  306.     windowX = DBWnd->LeftEdge;
  307.     windowY = DBWnd->TopEdge;
  308.     
  309.     GetVar("DELICONFIG",configdir,256,GVF_GLOBAL_ONLY);
  310.     sprintf(filename,"%s/%s",configdir,PREFSFILENAME);
  311.     
  312.     if(file = Open (filename,MODE_NEWFILE))
  313.     {
  314.         FPuts(file,adosname);
  315.         FPuts(file,"\n");
  316.         FPuts(file,insertscript);
  317.         FPuts(file,"\n");
  318.         FPuts(file,removescript);
  319.         FPuts(file,"\n");
  320.         FPuts(file,databasename);
  321.         FPuts(file,"\n");
  322.         FWrite(file,&(Popup),sizeof(BOOL),1);
  323.         FWrite(file,&(Activate),sizeof(BOOL),1);
  324.         FWrite(file,&(windowX),sizeof(ULONG),1);
  325.         FWrite(file,&(windowY),sizeof(ULONG),1);
  326.         FWrite(file,&(InsertDelay),sizeof(UWORD),1);
  327.         FWrite(file,&(RemoveDelay),sizeof(UWORD),1);
  328.         FWrite(file,&(ProgramMode),sizeof(UWORD),1);
  329.         Close(file);
  330.     }
  331. }
  332.  
  333. void loadPrefs (void)
  334. {
  335.     BPTR file;
  336.     char configdir[256];
  337.     char filename[512];
  338.  
  339.     GetVar("DELICONFIG",configdir,256,GVF_GLOBAL_ONLY);
  340.     sprintf(filename,"%s/%s",configdir,PREFSFILENAME);
  341.     
  342.     if(file = Open (filename,MODE_OLDFILE))
  343.     {
  344.         FGets(file,adosname,10);
  345.         adosname[strlen(adosname)-1]=0;
  346.         FGets(file,insertscript,256);
  347.         insertscript[strlen(insertscript)-1]=0;
  348.         FGets(file,removescript,256);
  349.         removescript[strlen(removescript)-1]=0;
  350.         FGets(file,databasename,256);
  351.         databasename[strlen(databasename)-1]=0;
  352.         FRead(file,&(Popup),sizeof(BOOL),1);
  353.         FRead(file,&(Activate),sizeof(BOOL),1);
  354.         FRead(file,&(windowX),sizeof(ULONG),1);
  355.         FRead(file,&(windowY),sizeof(ULONG),1);
  356.         FRead(file,&(InsertDelay),sizeof(UWORD),1);
  357.         FRead(file,&(RemoveDelay),sizeof(UWORD),1);
  358.         FRead(file,&(ProgramMode),sizeof(UWORD),1);
  359.         
  360.         Close(file);
  361.     }
  362.  
  363.     newDevice();
  364. }
  365.  
  366. ULONG appear (void)
  367. {
  368.     if (WINDOWSIGNAL) return WINDOWSIGNAL;
  369.  
  370.     if (Scr = dt_LockScreen())
  371.     {
  372.         ComputeFont( 0, 0 );
  373.  
  374.         if (VisualInfo = GetVisualInfo( Scr, TAG_DONE ))
  375.         {
  376.             if (!OpenDBWindow())
  377.             {
  378.                 /* transfer the prefs data into the gadgets and menus */
  379.             
  380.                 /* ok, this is a hack ;-) */
  381.             
  382.                 GetString(DBGadgets[GD_Gadget70]) = adosname;
  383.                 GetString(DBGadgets[GD_Gadget60]) = databasename;
  384.                 GetString(DBGadgets[GD_Gadget80]) = insertscript;
  385.                 GetString(DBGadgets[GD_Gadget90]) = removescript;
  386.  
  387.                 GT_SetGadgetAttrs(DBGadgets[GD_Gadget40],DBWnd,NULL,(GTCY_Active),(ProgramMode),(TAG_DONE));
  388.                 GT_SetGadgetAttrs(DBGadgets[GD_Gadget20],DBWnd,NULL,(GTSL_Level),(InsertDelay),(TAG_DONE));
  389.                 GT_SetGadgetAttrs(DBGadgets[GD_Gadget30],DBWnd,NULL,(GTSL_Level),(RemoveDelay),(TAG_DONE));
  390.  
  391.                 /* the menu hooks will be handled by the OpenDBWindow Function */
  392.  
  393.                 RefreshGadgets(DBWnd->FirstGadget,DBWnd,NULL);
  394.             
  395.                 WINDOWSIGNAL = (1L << DBWnd->UserPort->mp_SigBit);
  396.             }
  397.         }
  398.     }
  399.     
  400.     return WINDOWSIGNAL;
  401. }
  402.  
  403. ULONG disappear (void)
  404. {
  405.     if (WINDOWSIGNAL)
  406.     {
  407.         windowX = DBWnd->LeftEdge;
  408.         windowY = DBWnd->TopEdge;
  409.  
  410.         CloseDBWindow();
  411.  
  412.         if ( VisualInfo ) {
  413.             FreeVisualInfo( VisualInfo );
  414.             VisualInfo = NULL;
  415.         }
  416.  
  417.         if ( Scr ) {
  418.             dt_UnlockScreen();
  419.             Scr = NULL;
  420.         }
  421.         
  422.         WINDOWSIGNAL = 0;
  423.         return -1;
  424.     }
  425.     else return 0;    /* window was closed */
  426. }
  427.  
  428. void main(void)
  429. {
  430.     ULONG signals;
  431.     struct DeliMessage *msg;
  432. //    struct Process *proc;
  433. //    struct Window *oldptr;
  434.     struct MsgPort *timeport;
  435.     struct timerequest *timeior;
  436.  
  437.     if (!(changesignal = AllocSignal(-1))) return;
  438.  
  439. //    proc = FindTask(0L);
  440. //    oldptr = proc->pr_WindowPtr;
  441. //    proc->pr_WindowPtr = -1;
  442.  
  443.     loadPrefs();
  444.  
  445.     if (Popup) appear();
  446.  
  447.     if (timeport = CreateMsgPort())
  448.     {
  449.     if (timeior = (struct timerequest*) CreateIORequest(timeport,sizeof(struct timerequest)))
  450.     {
  451.     if (!OpenDevice("timer.device",UNIT_VBLANK,timeior,0))    // a stop-clock
  452.     {
  453.     while (running)
  454.     {
  455.         signals = Wait (DELISIGNAL|SIGBREAKF_CTRL_C|CHANGESIGNAL|WINDOWSIGNAL);
  456.  
  457.         if (signals & SIGBREAKF_CTRL_C) running=FALSE;
  458.  
  459.         if (Activate) if (signals & CHANGESIGNAL)
  460.         {
  461.             if (handler)
  462.             {
  463.                 UBYTE cmdline [512];
  464.                 UBYTE cmdline2 [512];
  465.                 
  466.                 ior->io_Command    = TD_CHANGESTATE;
  467.                 ior->io_Flags    = IOF_QUICK;
  468.                 ior->io_Length    = 0;
  469.                 DoIO(ior);
  470.  
  471.                 {
  472.                     if (ior->io_Actual)
  473.                     {
  474.                         ULONG tmpsig;
  475.                     
  476.                         timeior->tr_time.tv_secs    = 10; // (RemoveDelay/50);
  477.                         timeior->tr_node.io_Command    = TR_ADDREQUEST;
  478.                         timeior->tr_node.io_Flags    = IOF_QUICK;
  479.                         SendIO(timeior);
  480.                         
  481.                         tmpsig = Wait (TIMESIGNAL|CHANGESIGNAL|SIGBREAKF_CTRL_C);
  482.                         
  483.                         AbortIO(timeior);
  484.                         WaitIO(timeior);
  485.  
  486.                         ior->io_Command    = TD_CHANGESTATE;
  487.                         ior->io_Flags    = IOF_QUICK;
  488.                         ior->io_Length    = 0;
  489.                         DoIO(ior);
  490.                         
  491.                         if (ior->io_Actual)
  492.                         {
  493.                             sprintf(cmdline,"%s",removescript);
  494.                             sprintf(cmdline2,cmdline,databasename);
  495.                             Execute (cmdline2,NULL,NULL);
  496.                         }
  497.                     }
  498.                     
  499.                     if (!ior->io_Actual)
  500.                     {
  501.                         Delay(InsertDelay);
  502.                         getVolume();
  503.                         sprintf(cmdline,"%s",insertscript);
  504.                         sprintf(cmdline2,cmdline,volumename,databasename);
  505.                         Execute (cmdline2,NULL,NULL);
  506.                     }
  507.  
  508.                     
  509.                     switch (ProgramMode)
  510.                     {
  511.                         case IMMEDIATE:
  512.                             playlist(TRUE);
  513.                             break;
  514.                         case LOADNOPLAY:
  515.                             playlist(FALSE);
  516.                             break;
  517.                         case WAITSONGEND:
  518.                             waitplay = TRUE;
  519.                             break;
  520.                         default:
  521.                             break;
  522.                     }
  523.                 }
  524.             }
  525.         }
  526.  
  527.         if (signals & WINDOWSIGNAL) /* could be zero ! */
  528.         {
  529.             running = HandleDBIDCMP();
  530.             
  531.             if (running==2) disappear();    /* hide signal */
  532.         }
  533.  
  534.         if (signals & DELISIGNAL)
  535.         {
  536.             if (msg = (struct DeliMessage*)GetMsg(DeliPort))
  537.             {
  538.                 msg->Result = msg->Function();
  539.                 ReplyMsg((struct Message*)msg);
  540.             }
  541.         }
  542.  
  543.     } // while
  544.     CloseDevice(timeior);
  545.     }
  546.     DeleteIORequest((struct IORequest*)timeior);
  547.     }
  548.     DeleteMsgPort(timeport);
  549.     }
  550.  
  551.     remove_handler();
  552.  
  553.     disappear();
  554.  
  555.     FreeSignal(changesignal);
  556.  
  557. //    proc->pr_WindowPtr = oldptr;
  558. }
  559.